package org.example.cart.service.impl;

import org.example.cart.api.CouponService;
import org.example.cart.api.MemberService;
import org.example.cart.api.ProductService;
import org.example.cart.api.WareHouseService;
import org.example.cart.api.module.FullReduction;
import org.example.cart.api.module.Ladder;
import org.example.cart.api.module.Preferential;
import org.example.cart.api.module.SkuInfo;
import org.example.cart.constant.CartRedisConstants;
import org.example.cart.service.CartService;
import org.example.cart.vo.*;
import org.example.core.constant.TokenConstants;
import org.example.core.utils.R;
import org.example.redis.service.RedisService;
import org.example.security.handler.SecurityHandler;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @author 小杰_cc
 * @version 1.0
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisService redisService;
    @Autowired
    private ProductService productService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private WareHouseService wareHouseService;
    @Autowired
    private MemberService memberService;

    // 添加购物车
    @Override
    public void addCartSku(CartRestVo cartRestVo) {
        String memberId = SecurityHandler.getData().get(TokenConstants.MEMBER_ID);
        String redisKey = CartRedisConstants.MEMBER_CART + memberId;
        String redisHasKey = String.valueOf(cartRestVo.getSkuId());
        boolean existHasKey = redisService.existHasKey(redisKey, redisHasKey);
        // 已经存在
        CartItemVo cartItem;
        if (existHasKey){
            // 存在获取修改数量
            cartItem = redisService.getHashValue(redisKey, redisHasKey);
            cartItem.setCount(cartItem.getCount() + cartRestVo.getCount());
        }else {
            cartItem = new CartItemVo();
            cartItem.setSkuId(cartRestVo.getSkuId());
            cartItem.setCount(cartRestVo.getCount());
            cartItem.setSelected(true);
        }
        redisService.setHash(redisKey, redisHasKey, cartItem);
    }

    /**
     * 查看购物车
     */
    @Override
    public CartVo queryCartItem() {
        String member_id = SecurityHandler.getData().get(TokenConstants.MEMBER_ID);
        String redisKey = CartRedisConstants.MEMBER_CART + member_id;
        List<CartItemVo> values = redisService.getHashValues(redisKey);
        CartVo cartVo = null;
        if (values != null && !values.isEmpty()){
            cartVo = buildCart(values);
        }
        return cartVo;
    }

    /**
     * 修改购物车数据
     */
    @Override
    public void updateCart(CartRestVo cartRestVo) {
        String member_id = SecurityHandler.getData().get(TokenConstants.MEMBER_ID);
        String redisKey = CartRedisConstants.MEMBER_CART + member_id;
        String redisHasKey = String.valueOf(cartRestVo.getSkuId());
        CartItemVo cartItem = redisService.getHashValue(redisKey, redisHasKey);
        cartItem.setCount(cartRestVo.getCount());
        cartItem.setSelected(cartRestVo.getSelected());
        // 存入
        redisService.setHash(redisKey, redisHasKey, cartItem);
    }

    /**
     * 删除购物车数据
     * @param skuIds
     */
    @Override
    public void deleteCartItems(List<Long> skuIds) {
        String memberId = SecurityHandler.getData().get(TokenConstants.MEMBER_ID);
        String redisKey = CartRedisConstants.MEMBER_CART + memberId;
        String[] array = skuIds.stream().map(String::valueOf).toArray(String[]::new);
        redisService.deleteHashValue(redisKey, array);
    }

    /**
     * 获取购物车数量
     * @return
     */
    @Override
    public Long queryCartCount() {
        String member_id = SecurityHandler.getData().get(TokenConstants.MEMBER_ID);
        String redisKey = CartRedisConstants.MEMBER_CART + member_id;
        Long hashCount = redisService.getHashCount(redisKey);
        return hashCount;
    }

    /**
     * 获取所有选择的购物项
     */
    @Override
    public List<CartItemVo> querySelected() {
        String member_Id = SecurityHandler.getData().get(TokenConstants.MEMBER_ID);
        String redisKey = CartRedisConstants.MEMBER_CART + member_Id;
        List<CartItemVo> values = redisService.getHashValues(redisKey);
        List<CartItemVo> cartItemVos = values.stream().filter(CartItemVo::getSelected).collect(Collectors.toList());
        return cartItemVos;
    }

    /**
     * 移入收藏
     * @param moveCollectVo
     */
    @Override
    public R<?> moveCollect(MoveCollectVo moveCollectVo) {
        String memberId = SecurityHandler.getData().get(TokenConstants.MEMBER_ID);
        String redisKey = CartRedisConstants.MEMBER_CART + memberId;
        redisService.deleteHashValue(redisKey, moveCollectVo.getSkuId().toString());
        // 添加到收藏
        R<?> addCollect = memberService.addCollect(moveCollectVo.getSpuId(), memberId);
        if (addCollect.getCode() == 0){
            return R.ok();
        }
        return R.error();
    }

    @Override
    public void updateCartAll(Boolean selected) {
        String member_id = SecurityHandler.getData().get(TokenConstants.MEMBER_ID);
        String redisKey = CartRedisConstants.MEMBER_CART + member_id;
        Map<String, CartItemVo> hash = redisService.getHash(redisKey);
        for (Map.Entry<String, CartItemVo> entry : hash.entrySet()) {
            String key = entry.getKey(); // 获取键名
            CartItemVo cartItem = entry.getValue(); // 获取CartItemVo对象
            cartItem.setSelected(selected);
            cartItem.setCount(cartItem.getCount());
            cartItem.setSkuId(cartItem.getSkuId());
            hash.put(key, cartItem);
        }
        redisService.setHashAll(redisKey, hash);
    }

    // 构建购物车信息
    private CartVo buildCart(List<CartItemVo> values) {
        CartVo cartVo = new CartVo();
        List<Long> skuIds = values.stream().map(CartItemVo::getSkuId).collect(Collectors.toList());
        // 商品信息
        Map<Long, SkuInfo> skuInfos = productService.queryCartSkus(skuIds).getData();
        // 促销信息
        Map<Long, Preferential> preferential = couponService.getPreferential(skuIds).getData();
        // 库存信息
        Map<Long, Integer> stocks = wareHouseService.queryStocks(skuIds).getData();
        List<CartSkuVo> collect = values.stream().map(item -> {
            CartSkuVo cartSkuVo = new CartSkuVo();
            BeanUtils.copyProperties(skuInfos.get(item.getSkuId()), cartSkuVo);
            cartSkuVo.setStock(stocks.get(item.getSkuId()));
            cartSkuVo.setCount(item.getCount());
            cartSkuVo.setSelected(item.getSelected());
            return cartSkuVo;
        }).collect(Collectors.toList());

        List<CartSkuVo> cartItemVoList = buildPayPrice(collect, preferential);    // 构建到手价
        BigDecimal totalPrice = countTotalPrice(cartItemVoList);    // 总价（选中）
        BigDecimal payPrice = countPayPrice(cartItemVoList);    // 优惠之后的总价（选中）

        cartVo.setItems(cartItemVoList);
        cartVo.setTotalPrice(totalPrice.setScale(2, RoundingMode.HALF_UP));
        cartVo.setPayPrice(payPrice.setScale(2, RoundingMode.HALF_UP));

        return cartVo;
    }

    // 构建每个优惠后应付价格
    private List<CartSkuVo> buildPayPrice(List<CartSkuVo> cartSkuVos, Map<Long, Preferential> preferential) {
        BigDecimal compareDigit = new BigDecimal("0");
        List<CartSkuVo> itemList = cartSkuVos.stream().peek(item -> {
            // 数量
            BigDecimal skuCount = new BigDecimal(item.getCount());
            // 总价
            BigDecimal singleTotal = item.getPrice().multiply(skuCount);
            // 折扣
            BigDecimal ladderPrice = countLadderPrice(preferential.get(item.getSkuId()).getLadders(), item, singleTotal);
            // 满减
            BigDecimal fullPrice = countFullPrice(preferential.get(item.getSkuId()).getFullReductions(), singleTotal);
            // 找出最优价格
            if (ladderPrice.compareTo(compareDigit) > 0 && fullPrice.compareTo(compareDigit) > 0) {
                if (ladderPrice.compareTo(fullPrice) >= 0) {
                    item.setPayPrice(fullPrice.divide(skuCount, 2, RoundingMode.HALF_UP));
                } else {
                    item.setPayPrice(ladderPrice.divide(skuCount, 2, RoundingMode.HALF_UP));
                }
            } else if (ladderPrice.compareTo(compareDigit) > 0 && fullPrice.compareTo(compareDigit) <= 0) {
                item.setPayPrice(ladderPrice.divide(skuCount, 2, RoundingMode.HALF_UP));
            } else if (ladderPrice.compareTo(compareDigit) <= 0 && fullPrice.compareTo(compareDigit) > 0) {
                item.setPayPrice(fullPrice.divide(skuCount, 2, RoundingMode.HALF_UP));
            } else {
                item.setPayPrice(item.getPrice());
            }
        }).collect(Collectors.toList());

        return itemList;
    }

    // 计算购物车中选中的总价
    public BigDecimal countTotalPrice(List<CartSkuVo> cartSkuVos){
        BigDecimal totalPrice = new BigDecimal("0");
        for (CartSkuVo item : cartSkuVos) {
            // 选中,计算优惠
            if (item.getSelected()){
                BigDecimal singleTotal = item.getPrice().multiply(new BigDecimal(item.getCount()));
                totalPrice = totalPrice.add(singleTotal);
            }
        }
        return totalPrice;
    }

    // 计算购物车中选中的应付价格
    public BigDecimal countPayPrice(List<CartSkuVo> cartSkuVos){
        BigDecimal payPrice = new BigDecimal("0");
        for (CartSkuVo item : cartSkuVos) {
            // 选中,计算优惠
            if (item.getSelected()){
                BigDecimal singleTotal = item.getPayPrice().multiply(new BigDecimal(item.getCount()));
                payPrice = payPrice.add(singleTotal);
            }
        }
        return payPrice;
    }

    // 计算满减
    private BigDecimal countFullPrice(List<FullReduction> fullReductions, BigDecimal singleTotal) {
        BigDecimal fullPrice = new BigDecimal("0");
        if (fullReductions != null && fullReductions.size()>0){
            for (int j = 0; j< fullReductions.size(); j++){
                // 满足（查询时已经按full_price排序，这个满足直接结束）
                if (singleTotal.compareTo(fullReductions.get(j).getFullPrice())>=0){
                    fullPrice = singleTotal.subtract(fullReductions.get(j).getReducePrice());
                    return fullPrice;
                }
            }
        }
        return fullPrice;
    }

    // 计算则扣信息
    private BigDecimal countLadderPrice(List<Ladder> ladders, CartSkuVo cartSkuVo, BigDecimal singleTotal) {
        BigDecimal ladderPrice = new BigDecimal("0");
        if (ladders != null && ladders.size()>0){
            for (int i = 0; i< ladders.size(); i++){
                // 满足（查询时已经按count排序，这个满足直接结束）
                if (cartSkuVo.getCount() >= ladders.get(i).getCount()){
                    // 则扣后的价格
                    ladderPrice = singleTotal.multiply(ladders.get(i).getDiscount());
                    return ladderPrice;
                }
            }
        }
        return ladderPrice;
    }
}
